import pygame

from PyPixelCore.Setting import Color_type, show_rect_collision, block_surface_width, bar_width
from PyPixelCore.block.TextButton import TextButton

"""
    Bar --> TextButton --> TextBlock --> Block --> BaseBlock
    基础的滑动按钮
    可直接使用或者继承优化
    功能:
        不支持鼠标移入移出事件
        支持碰撞检测
        支持帧函数与计时器函数
        支持点击事件
        支持脏精灵优化
        支持滑动事件
        支持焦点事件
"""


class Bar(TextButton):
    def __init__(self, point_x=0, point_y=0, width=bar_width, real_height=200, bar_height=20, bar_direction=True, border_width=2,
                 layer=0,
                 is_alpha=False):
        self.bar_surf = None  # bar的中心按钮的样式
        self.bar_direction = True  # 默认为纵向的按钮(False为横向的按钮, 目前只支持纵向的bar)
        self.bar_height = bar_height
        self.bar_process = 0  # 0~1
        self.before_pos = None
        self.bar_point_y = 0
        self.real_height = real_height

        self.stream_move_link = base_stream_move_link
        self.link_block = None
        self.can_mouse_move_change = True  # True: 当前只能使用鼠标拖动 False: 当前只能使用滚轮拖动

        super().__init__(None, point_x, point_y, width, real_height - bar_height, border_width, layer, is_alpha)

    def _reload_image_first(self):
        self.font_color = Color_type.DEEP_GREY  # 中心按钮的颜色
        self.bk_color = Color_type.LIGHT_GREY  # 背景颜色
        self.border_color = Color_type.GREY  # 边框的颜色
        self.reload_bar_surf(self.bar_height)
        self.reload_image()


    def reload_bar_surf(self, bar_height):  # 可以重写获得更多的样式
        self.is_dirty = True
        self.bar_height = bar_height
        self.bar_surf = pygame.Surface((self.width, bar_height))
        self.bar_surf.fill(self.font_color)
        size = self.bar_surf.get_size()
        pygame.draw.line(self.bar_surf, self.border_color,
                         (size[0] / 2 - self.width * 0.1, size[1] * 0.2),
                         (size[0] / 2 - self.width * 0.1, size[1] * 0.8), width=int(self.width * 0.2))

    def reload_image(self):
        if not self.is_dirty:
            return
        self.is_dirty = False
        if self.is_alpha:
            self.image = pygame.Surface(
                (self.border_width * 2 + self.width, self.border_width * 2 + self.real_height)).convert_alpha()
        else:
            self.image = pygame.Surface(
                (self.border_width * 2 + self.width, self.border_width * 2 + self.real_height))

        self.image.fill(self.bk_color)
        self.rect.size = self.image.get_rect().size
        if self.border_width != 0:
            pygame.draw.rect(self.image, self.border_color, (0, 0, self.rect.width, self.rect.height),
                             width=self.border_width)
        # 绘制bar
        self.image.blit(self.bar_surf, (self.border_width, self.border_width + self.bar_process * (self.real_height - self.bar_height)))

    def mouse_hover_enter(self):  # 默认不支持鼠标移入事件
        pass

    def mouse_hover_leave(self):  # 默认不支持鼠标移出事件
        pass

    def click_down(self, pos):
        if self.real_height - self.bar_height == 0:  return
        # 中心点
        half_axis = self.bar_height/2
        # 修正后的纵坐标
        fixed_pos_y = pos[1] - self.border_width - self.collision_rect[1] - half_axis
        if fixed_pos_y < 0:  # 顶部
            new_bar_point_y = 0
        elif fixed_pos_y > self.real_height - self.bar_height:  # 底部
            new_bar_point_y = self.real_height - self.bar_height
        else:
            new_bar_point_y = fixed_pos_y
        self.bar_process = new_bar_point_y / (self.real_height - self.bar_height)

        if new_bar_point_y != self.bar_point_y:
            self.is_dirty = True
            self.bar_point_y = new_bar_point_y
        self.stream_move_link(self)

    def stream_move(self, pos):
        # 滑动bar的动画(暂时使用click_down代替)
        if self.before_pos:
            if self.real_height - self.bar_height == 0:  return
            offset = self.before_pos[1] - pos[1]
            self.before_pos = pos
            self.bar_point_y -= offset
            new_process =  self.bar_process +  offset / self.real_height
            if new_process > 1: new_process = 1
            if new_process < 0: new_process = 0
            if self.bar_process != new_process:
                self.bar_process = new_process
                self.is_dirty = True
                self.stream_move_link(self)
        else: self.before_pos = pos


    def click_up(self):
        pass

    def draw(self, surf):
        base_draw(self, surf)


def base_draw(self: Bar, surf):
    surf.blit(self.image, self.rect)
    if show_rect_collision:
        pygame.draw.rect(surf, Color_type.RED, self.rect, width=block_surface_width)

def base_stream_move_link(self):
    pass